﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace WellDone
{
    public sealed partial class EmployeeChecksDialog : Page
    {
        public event EventHandler CloseRequested;
        public bool bCanceled = false;
        public int iCheckNumber = 0, iSelectedIndex = 0;
        public string strReason = "";
        ObservableCollection<ServiceReferenceOpenRPOS.Login> EmployeeLoginRecords = new ObservableCollection<ServiceReferenceOpenRPOS.Login>();

        public EmployeeChecksDialog()
        {
            this.InitializeComponent();
        }
        public async Task<Boolean> init()
        {
            await loadEmployees();
            cmbEmployees.SelectedIndex = 0;
            return true;
        }
        private async Task<Boolean> loadEmployees()
        {
            // Retrieve order summary records for closed checks on selected date
            DateTime dtNow = await Globals.Now();
            string strFilter = "Status=" + Globals.k_int_status_closed.ToString() +
                " and TimeOpened between '" + dtNow.Date.Date.ToString() + "' and '" + dtNow.Date.Date.AddDays(1).ToString() + "'";
            Globals.OrderSummaryRecords = await Globals.client.GetOrderSummaryObjectsAsync(Globals.token, strFilter);
            // Initialize the combo box...
            cmbEmployees.Items.Clear();
            cmbEmployees.Items.Add("All");
            if (Globals.OrderSummaryRecords.Count > 0)
            {

                // Get a list of employees that correspond to the closed check records
                List<int> loginIDList = new List<int>();
                foreach (ServiceReferenceOpenRPOS.OrderSummary os in Globals.OrderSummaryRecords)
                    if (!loginIDList.Contains(os.col_LoginID))
                        loginIDList.Add(os.col_LoginID);
                string strLoginIDs = "";
                foreach (int loginID in loginIDList)
                    strLoginIDs += loginID.ToString() + ",";
                strLoginIDs = strLoginIDs.Substring(0, strLoginIDs.Length - 1);
                // Get employees associated with selected summary records
                EmployeeLoginRecords = await Globals.client.GetLoginObjectsAsync(Globals.token, "ID in (" + strLoginIDs + ") order by DisplayName");
                foreach (ServiceReferenceOpenRPOS.Login login in EmployeeLoginRecords)
                    cmbEmployees.Items.Add(login.col_DisplayName);
            }
            return true;
        }
        private async Task<Boolean> loadChecks()
        {
            // Retrieve order summary records for closed checks by selected user
            DateTime dtNow = await Globals.Now();
            string strFilter = "Status=" + Globals.k_int_status_closed.ToString() +
                " and TimeOpened between '" + dtNow.Date.Date.ToString() + "' and '" +
                dtNow.Date.Date.AddDays(1).ToString() +
                ((cmbEmployees.SelectedIndex>0)?("' and LoginID=" +
                EmployeeLoginRecords[cmbEmployees.SelectedIndex - 1].col_ID.ToString()) : ("'"));
            Globals.OrderSummaryRecords = await Globals.client.GetOrderSummaryObjectsAsync(Globals.token, strFilter);
            string strOrderSummaryIDs = "";
            Globals.OrderCheckRecords.Clear();
            if (Globals.OrderSummaryRecords.Count() > 0)
            {
                foreach (ServiceReferenceOpenRPOS.OrderSummary os in Globals.OrderSummaryRecords)
                    strOrderSummaryIDs += os.col_ID.ToString() + ",";
                strOrderSummaryIDs = strOrderSummaryIDs.Substring(0, strOrderSummaryIDs.Length - 1);
                Globals.OrderCheckRecords = await Globals.client.GetOrderCheckObjectsAsync(Globals.token,
                    "OrderSummaryID in (" + strOrderSummaryIDs + ") order by OrderSummaryID, ID");
            }
            lvCurrentEmployeeChecks.Items.Clear();
            EmployeeCheck ec;
            decimal dRunningTotal = 0;

            foreach (ServiceReferenceOpenRPOS.OrderCheck oc in Globals.OrderCheckRecords)
            {
                ec = new EmployeeCheck();
                ServiceReferenceOpenRPOS.OrderSummary os = Globals.OrderSummaryRecords.Where(x => x.col_ID == oc.col_OrderSummaryID).First();
                ec.OrderCheckID = oc.col_ID.ToString();
                ec.OrderSummaryID = oc.col_OrderSummaryID.ToString();
                ec.Table = os.col_CarryOut?"To Go":os.col_TableNumber.ToString();
                ec.Time = os.col_TimeSent.TimeOfDay.ToString();
                if (oc.col_PaymentType==0) {ec.Payment = "Cash";}
                else if (oc.col_PaymentType == 1) {ec.Payment = "Credit";}
                else
                {
                    foreach (ServiceReferenceOpenRPOS.PaymentType pt in Globals.PaymentTypeRecords)
                    { if (pt.col_ID == oc.col_PaymentType) ec.Payment = pt.col_Name;}
                }
                ec.Subtotal = oc.col_Subtotal.ToString("N");
                ec.Tax = oc.col_Tax.ToString("N");
                ec.Total = (oc.col_Subtotal + oc.col_Tax).ToString("N");
                dRunningTotal += oc.col_Subtotal + oc.col_Tax;
                lvCurrentEmployeeChecks.Items.Add(ec);
            }

            // Show the total
            ec = new EmployeeCheck();
            ec.Subtotal = "Total";
            ec.Total = dRunningTotal.ToString("N");
            lvCurrentEmployeeChecks.Items.Add(ec);

            return true;
        }

        private void btnClose_Click(object sender, RoutedEventArgs e)
        {
            // Close the dialog...
            if (this.CloseRequested != null)
            {
                this.CloseRequested(this, EventArgs.Empty);
            }
        }


        private async void cmbEmployees_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            await loadChecks();
        }

        private async void btnReprintCheck_Click(object sender, RoutedEventArgs e)
        {
            var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
            Object value = localSettings.Values[Globals.k_str_settings_receipt_print_route];
            // Re-print selected checks...
            foreach (EmployeeCheck ec in lvCurrentEmployeeChecks.SelectedItems)
            {
                // Update the print queue to print the order reciepts
                ServiceReferenceOpenRPOS.PrintQueue pq = new ServiceReferenceOpenRPOS.PrintQueue();
                pq.bFilterPrintOrder = true;
                pq.col_PrintOrder = false;
                pq.bFilterPrintReceipt = true;
                pq.col_PrintReceipt = true;
                pq.bFilterOrderCheckID = true;
                pq.col_OrderCheckID = Convert.ToInt32(ec.OrderCheckID);
                pq.bFilterOrderSummaryID = true;
                pq.col_OrderSummaryID = Convert.ToInt32(ec.OrderSummaryID);
                pq.bFilterPrinted = true;
                pq.col_Printed = false;
                pq.bFilterPrintSales = true;
                pq.col_PrintSales = false;
                pq.bFilterLoginID = true;
                pq.col_LoginID = 0;
                pq.bFilterPrintRoute = true;
                try
                {
                    pq.col_PrintRoute = Convert.ToByte(value);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.Message);
                }
                try
                {
                    await Globals.client.AddPrintQueueObjectAsync(Globals.token, pq);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.Message);
                }
            }
        }

        private async void btnPrintSales_Click(object sender, RoutedEventArgs e)
        {
            var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
            Object value = localSettings.Values[Globals.k_str_settings_receipt_print_route];
            // Print sales report for selected user... (or full report if "All" is selected...)
            ServiceReferenceOpenRPOS.PrintQueue pq = new ServiceReferenceOpenRPOS.PrintQueue();
            pq.bFilterPrintOrder = true;
            pq.col_PrintOrder = false;
            pq.bFilterPrintReceipt = true;
            pq.col_PrintReceipt = false;
            pq.bFilterOrderCheckID = false;
            pq.bFilterOrderSummaryID = false;
            pq.bFilterPrinted = true;
            pq.col_Printed = false;
            pq.bFilterPrintSales = true;
            pq.col_PrintSales = true;
            pq.bFilterLoginID = true;
            pq.col_LoginID = (cmbEmployees.SelectedIndex > 0) ? EmployeeLoginRecords[cmbEmployees.SelectedIndex - 1].col_ID : 0;
            pq.bFilterPrintRoute = true;
            try
            {
                pq.col_PrintRoute = Convert.ToByte(value);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
            try
            {
                await Globals.client.AddPrintQueueObjectAsync(Globals.token, pq);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
        }

        private void lvCurrentEmployeeChecks_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // Ensure that the "Total" line is not selected...
            if (lvCurrentEmployeeChecks.Items.Count() > 0)
                lvCurrentEmployeeChecks.SelectedItems.Remove(lvCurrentEmployeeChecks.Items[lvCurrentEmployeeChecks.Items.Count() - 1]);
            // Enable "Reprint Check" button if any checks are selected...            
            btnReprintCheck.IsEnabled = (lvCurrentEmployeeChecks.SelectedItems.Count() > 0);
        }
    }

    public class EmployeeCheck
    {
        public string OrderSummaryID { get; set; }
        public string Table { get; set; }
        public string Time { get; set; }
        public string OrderCheckID { get; set; }
        public string Payment { get; set; }
        public string Subtotal { get; set; }
        public string Tax { get; set; }
        public string Total { get; set; }
    }
}
